<template>
	<div>
		<div ref="map" style="width: 100%;height:600px;"></div>
		<div class="menuBar">
			<input type="button" value="开始" @click="startClick()" />
			<input type="button" value="暂停" @click="pauseClick()" />
			<input type="button" value="停止" @click="stopClick()" />
		</div>
	</div>
</template>

<script>
	import mapboxgl from 'mapbox-gl';
	import * as turf from '@turf/turf';
	export default {
		data() {
			return {
				isPlay: false,
				counter: 0,
				steps: 0,
				aLength: 0,
				routeGeoJson: {
					'type': 'FeatureCollection',
					'features': [{
						'type': 'Feature',
						'geometry': {
							'type': 'LineString',
							'coordinates': [
								[116.391844, 39.898457],
								[116.377947, 39.898595],
								[116.368001, 39.898341],
								[116.357144, 39.898063],
								[116.351934, 39.899095],
								[116.35067, 39.905871],
								[116.3498, 39.922329],
								[116.349671, 39.931017],
								[116.349225, 39.939104],
								[116.34991, 39.942233],
								[116.366892, 39.947263],
								[116.387537, 39.947568],
								[116.401988, 39.947764],
								[116.410824, 39.947929],
								[116.42674, 39.947558],
								[116.427338, 39.9397],
								[116.427919, 39.932404],
								[116.428377, 39.923109],
								[116.429583, 39.907094],
								[116.41404, 39.906858],
								[116.405321, 39.906622],
								[116.394954, 39.906324],
								[116.391264, 39.906308],
								[116.390748, 39.916611]
							]
						}
					}]
				},
				realRouteGeoJson: {
					'type': 'FeatureCollection',
					'features': [{
						'type': 'Feature',
						'geometry': {
							'type': 'LineString',
							'coordinates': []
						}
					}]
				},
				animatePointGeoJson: {
					'type': 'FeatureCollection',
					'features': [{
						'type': 'Feature',
						'properties': {},
						'geometry': {
							'type': 'Point',
							'coordinates': []
						}
					}]
				},
				newRouteGeoJson: {
				}
			};
		},
		mounted() {
			this.init();
		},
		methods: {
			init() {
				mapboxgl.accessToken =
					'pk.eyJ1IjoibGVpeXV5YW4iLCJhIjoiY2trZzltajd6MGhsMDJvcW43bHBna3c2biJ9.OE_79L9HaZAe6nnr8VYLTA';
				const map = new mapboxgl.Map({
					container: this.$refs.map, // container id
					style: 'mapbox://styles/mapbox/streets-v11', // style URL
					center: [116.390619, 39.924317], // starting position [lng, lat]
					zoom: 13 // starting zoom
				});
				this.map = map;
				map.setStyle('mapbox://styles/mapbox/dark-v9');
				// 箭头-右
				var svgXML =
					`<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> 
				                <path d="M529.6128 512L239.9232 222.4128 384.7168 77.5168 819.2 512 384.7168 946.4832 239.9232 801.5872z" p-id="9085" fill="#ffffff"></path> 
				            </svg>
				            `
				// 箭头-上
				// var svgXML =
				// `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> 
				//     <path d="M957.3 543.4L870.7 630 512.1 271.5 152.3 631.3l-86.6-86.6L512.1 98.2z" p-id="9085" fill="#ffffff"></path> 
				// </svg>
				// `
        let planeSVG =
          `<svg width="1660" height="849" xmlns="http://www.w3.org/2000/svg">
              <!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ -->
              <path id="svg_1" d="m799.932139,780.797356c40.40007,14.238526 113.475497,-52.256258 39.85481,-56.149306c-49.829692,-33.019578 110.468339,-9.454209 45.145331,-79.189561c-69.885566,-16.019274 -124.517525,-72.021056 -148.850652,-143.660073c-28.426744,-77.170834 -120.959676,-55.969377 -181.586143,-78.2671c-120.983927,-22.739661 -241.831072,-49.618032 -364.87983,-56.253163c-40.922505,48.548741 -60.220733,152.845052 -133.042294,148.777966c-72.795226,-38.56081 3.074423,-135.365958 -18.736179,-190.668818c-42.758764,-15.16786 -34.601872,-44.597872 7.09858,-48.322949c63.622048,-46.227687 10.68858,-135.587764 -3.154034,-196.482399c-33.675622,-57.836883 38.437289,-108.831848 65.915398,-40.586007c35.013642,71.176747 55.339622,149.326764 83.150001,223.947055c8.677627,47.868361 72.999767,20.72954 106.688063,35.009655c142.056909,16.089859 284.249063,32.263357 427.070751,38.487915c71.544992,-32.497525 147.470824,-59.728187 226.596723,-48.180161c55.33655,17.654634 86.5889,-4.103418 84.130623,-64.340894c31.416839,-86.764134 -76.985462,-48.122745 -125.859331,-60.893248c-194.980886,-9.983425 -390.53792,-13.006346 -585.447699,-0.736871c-43.272695,-11.368329 57.153661,-10.33612 72.392783,-12.949508c205.662168,-11.438105 411.760358,-5.811501 617.475856,-15.538693c59.319227,-23.035056 118.195411,17.981971 178.674563,11.035388c152.544514,6.579505 305.22592,8.869945 457.888122,9.368894c-43.157038,33.771987 -123.661942,0.333345 -180.748447,8.699547c-114.715526,-3.707979 -230.158194,-7.18595 -344.199031,9.254063c-44.417806,45.179363 -21.099483,141.658617 34.480783,164.13107c56.641541,32.059399 114.76304,60.162962 166.328257,98.26312c32.589986,65.347167 124.703247,120.176148 97.534363,202.46372c-31.136198,68.093407 -144.039716,25.278131 -172.626395,44.427878c21.149027,39.4567 94.18303,43.447251 107.317981,57.87258c-72.01278,21.837301 -3.347602,68.467648 37.610621,53.66623c50.542732,12.598257 -51.391346,21.446945 -68.219995,17.304538c-81.880618,0.693376 -163.711363,-3.015296 -245.571461,-4.200574c79.099344,-3.715835 158.424188,-3.640917 237.280695,-11.897545c-18.393595,-79.617751 -115.574949,-40.673805 -171.570661,-54.492054c-27.29727,-14.73349 -117.275251,3.95676 -71.661856,33.030033c25.45108,-12.071928 87.657802,-0.52627 31.000514,13.010158c-102.475387,3.483227 -205.336154,5.041994 -307.480808,-5.94083l0,-0.000058zm249.41988,-33.087044c-31.234902,-47.57389 -139.176492,-38.433098 -158.820322,4.899033c38.26457,32.413192 117.228615,21.133182 157.94389,1.501236l0.876432,-6.400327l0,0l0,0.000058zm225.780425,-27.70668c-46.038552,-34.199022 -130.29608,-37.973254 -171.657679,-10.171845c51.936222,26.148143 115.640624,15.506577 171.657679,10.171845zm-227.477873,-15.665827c48.918749,-43.949781 -86.308314,-35.769978 -116.202728,-33.530137c-73.933479,35.405557 29.993447,45.183753 61.041859,39.380454c18.49817,-0.128405 37.072878,-1.589728 55.160923,-5.850317l-0.000055,0z" stroke-width="1.5" stroke="#000" fill="#02e5e5"/>
          </svg>`;
				//给图片对象写入base64编码的svg流
				var svgBase64 = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgXML)));
        let planeBase64 = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(planeSVG)));
        planeBase64 = '';
				let that = this;
				map.on('load', function() {
					let arrowIcon = new Image(20, 20)
					arrowIcon.src = svgBase64
					arrowIcon.onload = function() {
						map.addImage('arrowIcon', arrowIcon)
						let carIcon = new Image(100, 100);
						//carIcon.src = require('../assets/img/plane.png');
            carIcon.src = planeBase64;
						carIcon.onload = function() {
							//console.log('carIcon', carIcon);
							map.addImage('carIcon', carIcon);
							that.setRouteData()
						}
					}
				});
			},
			// 获取轨迹数据
			setRouteData() {
				this.animatePointGeoJson.features[0].geometry.coordinates = this.routeGeoJson.features[0].geometry
					.coordinates[0]
				this.aLength = this.routeGeoJson.features[0].geometry.coordinates.length;
				this.newRouteGeoJson = this.resetRoute(this.routeGeoJson.features[0], 1000, 'kilometers')
				this.steps = this.newRouteGeoJson.geometry.coordinates.length

				this.addRoutelayer() // 添加轨迹线图层
				this.addRealRouteSource() // 添加实时轨迹线图层
				this.addArrowlayer() // 添加箭头图层
				this.addAnimatePointSource() // 添加动态点图层
			},
			// 添加轨迹线图层
			addRoutelayer() {
				this.map.addLayer({
					'id': 'routeLayer',
					'type': 'line',
					'source': {
						'type': 'geojson',
						'lineMetrics': true,
						'data': this.routeGeoJson
					},
					'paint': {
						'line-width': 10,
						'line-opacity': 1,
						'line-color': '#009EFF',
					}
				});
			},
			// 添加实时轨迹线
			addRealRouteSource() {
				this.map.addLayer({
					'id': 'realRouteLayer',
					'type': 'line',
					'source': {
						'type': 'geojson',
						'lineMetrics': true,
						'data': this.realRouteGeoJson
					},
					'paint': {
						'line-width': 10,
						'line-opacity': 1,
						'line-color': '#FF9900',
					}
				});
			},
			// 添加箭头图层
			addArrowlayer() {
				this.map.addLayer({
					'id': 'arrowLayer',
					'type': 'symbol',
					'source': {
						'type': 'geojson',
						'data': this.routeGeoJson //轨迹geojson格式数据
					},
					'layout': {
						'symbol-placement': 'line',
						'symbol-spacing': 50, // 图标间隔，默认为250
						'icon-image': 'arrowIcon', //箭头图标
						'icon-size': 0.5
					}
				});
			},
			// 添加动态点图层
			addAnimatePointSource() {
				this.map.addLayer({
					'id': 'animatePointLayer',
					'type': 'symbol',
					'source': {
						'type': 'geojson',
						'data': this.animatePointGeoJson
					},
					'layout': {
						'icon-image': 'carIcon',
						'icon-size': 0.5,
						'icon-rotate': ['get', 'bearing'],
						'icon-rotation-alignment': 'map',
						'icon-allow-overlap': true,
						'icon-ignore-placement': true
					}
				});

				this.animate()
			},
			animate() {
				if (this.counter >= this.steps) {
					return
				}
				var startPnt, endPnt;
				if (this.counter == 0) {
					this.realRouteGeoJson.features[0].geometry.coordinates = []
					startPnt = this.newRouteGeoJson.geometry.coordinates[this.counter]
					endPnt = this.newRouteGeoJson.geometry.coordinates[this.counter + 1]
				} else if (this.counter !== 0) {
					startPnt = this.newRouteGeoJson.geometry.coordinates[this.counter - 1]
					endPnt = this.newRouteGeoJson.geometry.coordinates[this.counter]
				}

				this.animatePointGeoJson.features[0].properties.bearing = turf.bearing(
					turf.point(startPnt),
					turf.point(endPnt)
				) - 90;
				this.animatePointGeoJson.features[0].geometry.coordinates = this.newRouteGeoJson.geometry.coordinates[this.counter];
				this.realRouteGeoJson.features[0].geometry.coordinates.push(this.animatePointGeoJson.features[0].geometry
					.coordinates)

				this.map.getSource('animatePointLayer').setData(this.animatePointGeoJson);
				this.map.getSource('realRouteLayer').setData(this.realRouteGeoJson);
				if (this.isPlay) {
					setTimeout(() => {
						this.animate()
					}, 10)
					//requestAnimationFrame(this.animate);
				}

				this.counter = this.counter + 1;
			},
			resetRoute(route, nstep, units) {
				var newroute = {
					'type': 'Feature',
					'geometry': {
						'type': 'LineString',
						'coordinates': []
					}
				}
				var lineDistance = turf.lineDistance(route);
				var nDistance = lineDistance / nstep;
				for (let i = 0; i < this.aLength - 1; i++) {
					var from = turf.point(route.geometry.coordinates[i]);
					var to = turf.point(route.geometry.coordinates[i + 1]);
					let lDistance = turf.distance(from, to, units);
					if (i == 0) {
						newroute.geometry.coordinates.push(route.geometry.coordinates[0])
					}
					if (lDistance > nDistance) {
						let rings = this.lineMore(from, to, lDistance, nDistance, units)
						newroute.geometry.coordinates = newroute.geometry.coordinates.concat(rings)
					} else {
						newroute.geometry.coordinates.push(route.geometry.coordinates[i + 1])
					}
				}
				return newroute
			},
			lineMore(from, to, distance, splitLength, units) {
				var step = parseInt(distance / splitLength)
				var leftLength = distance - step * splitLength
				var rings = []
				var route = turf.lineString([from.geometry.coordinates, to.geometry.coordinates])
				for (let i = 1; i <= step; i++) {
					let nlength = i * splitLength
					let pnt = turf.along(route, nlength, units);
					rings.push(pnt.geometry.coordinates)
				}
				if (leftLength > 0) {
					rings.push(to.geometry.coordinates)
				}
				return rings
			},
			startClick() {
				if (!this.isPlay) {
					this.isPlay = true
					this.animate()
				}
			},
			pauseClick() {
				this.isPlay = false
				this.animate()
			},
			stopClick() {
				this.isPlay = false
				this.counter = 0
				this.animate()
			}
		}
	}
</script>

<style>
	.menuBar {
		position: relative;
		top: 10px;
		margin: 0 50px;
		padding: 5px;
		border-radius: 3px;
		z-index: 999;
		background-color: rgba(0, 168, 0, 0.7);
	}

	input[type=button] {
		font-size: 16px;
	}

	.mapboxgl-ctrl {
		display: none !important;
	}
</style>
